﻿// FileSystem
// 
// Class wrapping file system functionality.
// Wrapper was introduced to make TempFileManager unit testable.
// 
// FLMScan - Featured by FabLab Munich

using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using log4net;
using System.Runtime.InteropServices;

namespace FLMScan.Tools
{
    class FileSystem : IFileSystem        
    {
        private ILog logger;

        public FileSystem()
        {
            logger = LogManager.GetLogger(typeof(FileSystem));
        }

        bool IFileSystem.DirectoryExists(String path)
        {
            return Directory.Exists(path);            
        }

        bool IFileSystem.FileExists(String path)
        {
            return File.Exists(path);
        }

        List<String> IFileSystem.GetDirectories(String path)
        {
            List<String> directories = new List<string>();

            foreach(string directory in Directory.GetDirectories(path))
                directories.Add(directory);

            return directories;
        }
                
        public List<String> Deserialize(String path)
        {
            List<String> fileContents = new List<string>();

            try
            {
                StreamReader reader = File.OpenText(path);
                
                while(reader.Peek() >= 0)
                {
                    fileContents.Add(reader.ReadLine());
                }
            }
            catch(IOException ex)
            {
                logger.Warn("Text file deserialization failed!", ex);
            }

            return fileContents;
        }

        public bool Serialize(List<String> contents, String path)
        {
            try
            {
                StreamWriter writer = File.CreateText(path);
                foreach (String line in contents)
                {
                    writer.WriteLine(line);
                }

                writer.Close();
                return true;
            }
            catch (UnauthorizedAccessException ex)
            {
                logger.Warn("Text file serialization failed!", ex);
            }
            catch (ArgumentNullException ex)
            {
                logger.Warn("Text file serialization failed!", ex);
            }
            catch (ArgumentException ex)
            {
                logger.Warn("Text file serialization failed!", ex);
            }
            catch (PathTooLongException ex)
            {
                logger.Warn("Text file serialization failed!", ex);
            }
            catch (DirectoryNotFoundException ex)
            {
                logger.Warn("Text file serialization failed!", ex);
            }
            catch (NotSupportedException ex)
            {
                logger.Warn("Text file serialization failed!", ex);
            }

            return false;
        }

        public bool CreateDirectory(String path)
        {
            try
            {
                DirectoryInfo info = Directory.CreateDirectory(path);                
                return true;
            }
            catch (UnauthorizedAccessException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }
            catch (ArgumentNullException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }
            catch (ArgumentException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }
            catch (PathTooLongException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }
            catch (DirectoryNotFoundException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }
            catch (IOException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }
            catch (NotSupportedException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }

            return false;
        }

        public bool Serialize(Bitmap bitmap, String path)
        {
            try
            {
                bitmap.Save(path, System.Drawing.Imaging.ImageFormat.Tiff);
                return true;
            }
            catch (ArgumentNullException ex)
            {
                logger.Warn("Bitmap serialization failed!", ex);
            }
            catch (ExternalException ex)
            {
                logger.Warn("Bitmap serialization failed!", ex);
            }

            return false;
        }

        public bool Copy(String sourcePath, String destinationPath)
        {
            if (CreateDirectory(destinationPath))
            {

                foreach (string file in Directory.GetFiles(sourcePath))
                {
                    String fileName = Path.GetFileName(file);
                    File.Copy(file, Path.Combine(destinationPath, fileName));
                }

                return true;
            }
            else
                return false;            
        }

        public bool Delete(String path)
        {
            try
            {
                Directory.Delete(path, true);
            }
            catch (UnauthorizedAccessException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }
            catch (ArgumentNullException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }
            catch (ArgumentException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }
            catch (PathTooLongException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }
            catch (DirectoryNotFoundException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }
            catch (IOException ex)
            {
                logger.Warn("Directory creation failed!", ex);
            }            

            return true;
        }
    }
}
